package com.glp.work.flow.handler;

import java.util.List;

import org.flowable.common.engine.api.FlowableException;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import com.glp.common.reponse.BaseResult;
import com.glp.work.flow.constant.APICode;
import com.glp.work.flow.exception.APIException;
import com.glp.work.flow.exception.WorkflowException;
import com.glp.work.flow.utils.TraceIDUtils;

import lombok.extern.slf4j.Slf4j;


/**
 * @author liwenhong
 * @title 统一异常处理
 * @date 2018/11/13.
 */
@ControllerAdvice
@Slf4j
public class GlobalExceptionHandler {


    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public BaseResult<Object> jsonErrorHandler(Exception e) {
        log.error("service operation errors::", e);
        
        if (e instanceof APIException) {
            APIException ex = (APIException) e;
            if (ex.getApiCode().equals(APICode.AUTH_EXPIRE)) {
                return new BaseResult<>(APICode.NO_PERMISSIONS.getCode(), ex.getMessage()+TraceIDUtils.getLogTraceId());
            }
            return new BaseResult<>(ex.getApiCode().getCode(), e.getMessage());
        }
        if(e instanceof WorkflowException) {
        	//业务处理异常
        	return new BaseResult<>(APICode.WORKFLOW_CHECK_DATA_FAIL.getCode(), e.getMessage()+TraceIDUtils.getLogTraceId());
        }
        if(e instanceof FlowableException) {
			log.error("工作流引擎启动失败！请检查定义的流程模板！", e);
			return new BaseResult<>(APICode.WORKFLOW_CHECK_DATA_FAIL.getCode(), "工作流引擎启动失败！请检查定义的流程模板！"+TraceIDUtils.getLogTraceId());
        }
        if (e instanceof MethodArgumentNotValidException) {
            MethodArgumentNotValidException ex = (MethodArgumentNotValidException) e;
            return new BaseResult<>(APICode.ERROR.getCode(), handlerMessage(ex.getBindingResult())+TraceIDUtils.getLogTraceId());
        }
        if (e instanceof BindException) {
            BindException ex = (BindException) e;
            return  new BaseResult<>(APICode.ERROR.getCode(), handlerMessage(ex.getBindingResult())+TraceIDUtils.getLogTraceId());
        }
        if(e instanceof Exception) {
        	return new BaseResult<>(APICode.ERROR.getCode(), "服务异常！"+TraceIDUtils.getLogTraceId(), e.getMessage());
        }
        return new BaseResult<>(APICode.ERROR.getCode(), "服务异常！"+TraceIDUtils.getLogTraceId());
    }


    /**
     * 对方法参数校验异常错误信息的处理方法
     */
    private String handlerMessage(BindingResult result) {
        StringBuilder message = new StringBuilder();

        if (null != result && result.hasErrors()) {
            List<FieldError> fieldErrors = result.getFieldErrors();
            fieldErrors.forEach(error ->
                    message.append(error.getField()).append(":").append(error.getDefaultMessage()).append(" "));
        }
        return message.toString();
    }
}
